﻿using System.Collections;
using System.Collections.Generic;
using System.Text;
using Microsoft.Office.Interop.Outlook;
using AFS.VisitationRequestTool.Addin.Common;
using AFS.VisitationRequestTool.Addin.Variables;

namespace AFS.VisitationRequestTool.Addin.Entities
{
    public abstract class Person
    {
        // Refactored PersonObject into 1 abstract and 2 dervived classes 
        // TODO: Look at derived classes, just using them to differentiate object types, but what value is there?  

        private string displayName;
        private string accountID;
        //private bool isAFSUser;
       
        private UserType accountType;

        public Person(string displayName, string accountID)
        {
            this.displayName = displayName;
            this.accountID = accountID;

            if (accountID.ToLower().Contains("accenturefederal.com"))
            {
                accountType = UserType.AFS;
                // isAFSUser = true;
            }
            else
            {
                //isAFSUser = false;
                //isACNUser = false;

                if (accountID.Contains("accenture.com"))
                {
                    accountType = UserType.Accenture;
                }
                else if (accountID.Contains("avanade.com"))
                {
                    accountType = UserType.Accenture;
                }
                else if (accountID.Contains("navitaire.com"))
                {
                    accountType = UserType.Navitaire;
                }
                else
                {
                    accountType = UserType.Other;
                }
            }
        }

        public string DisplayName
        {
            get { return displayName; }
            //set { displayName = value; }
        }

        public string AccountID
        {
            get { return accountID; }
            //set { accountID = value; }
        }

        public UserType AccountType
        {
            get { return accountType; }
        }

        //public bool IsAFSUser
        //{
        //    get { return isAFSUser; }
        //}

        //#region IEnumerable Members

        //public IEnumerator<T> GetEnumerator()
        //{
        //    foreach (T t in m_Items)
        //    {
        //        // Lets check for end of list (it's bad code since we used arrays)
        //        if (t == null) // this wont work is T is not a nullable type
        //        {
        //            break;
        //        }

        //        // Return the current element and then on next function call 
        //        // resume from next element rather than starting all over again;
        //        yield return t;
        //    }
        //}

        //System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        //{
        //    // Lets call the generic version here
        //    return this.GetEnumerator();
        //}

        //#endregion
    }

    public class MeetingRecipient : Person
    {
        public MeetingRecipient(Recipient recipient) :
            base(recipient.AddressEntry.Name, GetRecipientEmailAddress(recipient)) // Keeping email formatter at MeethingRecipient level, since not all people are meeting recipients
        {

        }

        private static string GetRecipientEmailAddress(Recipient recipient)
        {
            // From mapitags.h file: http://sourcecodebrowser.com/p3scan/2.1/mapitags_8h_source.html
            // MSDN reference: http://msdn.microsoft.com/en-us/library/office/cc815489.aspx
            const string PR_SMTP_ADDRESS = "http://schemas.microsoft.com/mapi/proptag/0x39FE001E";
            string smtpAddress = System.String.Empty;

            try
            {
                Microsoft.Office.Interop.Outlook.PropertyAccessor pa = recipient.PropertyAccessor;
                smtpAddress = pa.GetProperty(PR_SMTP_ADDRESS).ToString();
            }
            catch (System.Runtime.InteropServices.COMException ex) // COMException is thrown b\c unresolved email resolves to MAPI property schema name
            {
                Logger.Error(ex.ToString());
                System.Windows.Forms.MessageBox.Show(@"One of the email addresses that you entered seems to be invalid.\n
                Please correct and try submitting again.\n
                If you continue to receive this error in spite of having correct emails addresses listed, please contact itsupport@accenturefederal.com");
                throw new InvalidEmailException();
            }

            return smtpAddress;
            //#if DEBUG
            //     System.Diagnostics.Debug.WriteLine(recip.Name + " SMTP=" + smtpAddress);
            //#endif   
        }

        public bool UploadVisitationRequest()
        {
            throw new System.Exception("Method not implemented.");
            
            if (this.AccountType == UserType.Accenture)
                return true;
            else
                return false;
        }
    }

    // TODO: not much value here.
    public class MeetingOrganizer : MeetingRecipient
    {
        public MeetingOrganizer(Recipient recipient) :
            base(recipient)
        {
            
        }

        public bool CancelMeeting(AppointmentItem meeting)
        {
            throw new System.Exception("Method not implemented.");
            return false;
        }

        public bool PushMeetingUpdate(AppointmentItem meeting)
        {
            throw new System.Exception("Method not implemented.");
            return false;
        }
    }

    public enum UserType
    {
        AFS = 0,
        Accenture = 1,
        Avanade = 2,
        Navitaire = 3,
        Other = 4
    }

    public class Persons : List<Person>
    {
        //private List<Person> persons;
        private bool containsAFS = false;
        private bool containsACN = false;
       
        public Persons()
        {

        }

        public bool ContainsACN
        {
            get { return containsACN; }
            set { containsACN = value; }
        }


        public bool ContainsAFS
        {
            get { return containsAFS; }
            set { containsAFS = value; }
        }

        // TODO: Need to take strong look at this. Taking shortcut by inherited from List<T> and letting it handle IEnumerable, etc. No virtuals, so just shadowing base.Add(T item) explcitly. 
        // <Person>Persons isn't being used polymorphically, but can be in future.        
        public new void Add(Person person)
        {
            base.Add(person);

            if (!containsAFS && person.AccountType == UserType.AFS)
            {
                containsAFS = true;                
            }
            if (!containsACN && (person.AccountType == UserType.Accenture || person.AccountType == UserType.Avanade || person.AccountType == UserType.Navitaire))
            {
                containsACN = true;
            }
        }
    }
}
